由于静态数据成员要实际在分配空间,因此不能在类声明中进行初始化。静态数据成员初始化在类的外部进行,且与一般数据成员初始化不同,它的格式如下:<数据类型><类名>::<静态数据成员名>=<值>
1)在编译阶段就分配空间。对象还没有创建;
2)必须在类中声明,在类外初始化(或定义)。
3)归同一个类的所有对象所有,共享同一个静态变量。在为对象分配的空间中不包含静态成员所占空间
4)有权限限制:private静态变量和 public静态变量。
private静态变量;在类(print类)外不能访问和操作。 类外访问:print::a;//erro 类外操作:print::a = 6;//erro
public静态变量;在类(print类)外可以访问和操作。 类外访问:print::a;//yes 类外操作:print::a = 6;//yes
5)const 静态成员变量(const static int a = 8);
定义静态变量 const 静态成员变量时,最好在类的内部初始化。
静态变量的调用:
用类名加域作用符: print::a;
用对象名加取址符: class p1; p1.a;
静态成员函数:(主要是为了访问静态变量)
与静态变量一样,在没有创建对象前即可通过类名调用。
1)静态成员函数只能访问 "静态成员变量",不能访问普通成员变量。
2)静态成员函数的使用规则和静态成员变量一样
3)静态成员函数也有使用权限。类外无法访问私有静态函数。
4)普通成员函数可访问"静态成员变量",也可访问"非静态成员变量"
类中可以包含静态数据成员和静态函数成员,统称为静态成员。默认情况下,静态成员的作用域是类范围内且是外部链接的。静态成员在内存中只有一个副本,不是类对象的一部分,而是独立的对象。因此,静态数据成员的声明不是定义,声明在类作用域内完成,而定义在文件作用域内完成。
class BufferedOutput { public: short BytesWritten() { return bytecount;} static void ResetCount() { bytecout = 0;} static long bytecount; }; long BufferedOutput::bytecount = 8;
静态成员的存在不依赖于对象实例,因此可以使用成员选择符访问,也可以不使用类对象访问。
BufferedOutput Console;
long nBytes = Console.bytecount;
lont nBytes = BufferedOutput::bytecount;
static 成员变量不属于对象的一部份,而是类别的一部份,所以程序可以在还没有诞生任何对象的时候就处理此种成员变量。但首先你必须初始化它。不要把static 成员变量的初始化动作安排在类别的构造式中,因为构造式可能一再被调用,而变量的初值却只应该设定一次。也不要把初始化动作安排在头文件中,因为它可能会被包含许多地方,因此也就可能被执行许多次。你应该在实作档中且类别以外的任何位置设定其初值。例如在main 之中,或全域函数中,或任何函数之外:
double SavingAccount::m_rate = 0.0075; // 设立static 成员变量的初值
void main() { ... }
对于静态(static)对象,当对象诞生时其构造式被执行;当程序将结束时(此对象因而将遭致毁灭)其析构式才被执行,但比全域对象的析构式早一步执行。
但静态数据成员属于类,因此定义对象时并不为静态成员分配空间。
为静态成员分配空间称为静态成员的定义
静态成员的定义一般出现在类的实现文件中。如在SavingAccount类的实现文件中,必须要如下的定义:
double SavingAccount::rate = 0.05;
该定义为rate分配了空间,并给它赋了一个初值0.05。
如果没有这个定义,连接器会报告一个错误。
可以通过作用域操作符从类直接调用。如: SavingAccount::rate
但从每个对象的角度来看,它似乎又是对象的一部分,因此又可以从对象引用它。如有个SavingAccount类的对象obj,则可以用:obj.rate
由于是整个类共享的,因此不管用哪种调用方式,得到的值都是相同的
定义静态成员函数的主要目的是访问静态的数据成员。
如在SavingAccount类中,当利率发生变化时,必须修改这个静态数据成员的值。为此可以设置一个静态的成员函数
static void SetRate(double newRate) {rate = newRate;}
静态成员函数可定义为内嵌的,也可在类外定义。在类外定义时,不用static。
静态成员函数的访问:可以通过类作用域限定符或通过对象访问
类名::静态成员函数名()
静态数据成员有什么特征?有什么用途?
不管这个类有多少个对象,静态数据成员都只有一份拷贝。静态数据成员一般用来保存整个类所有对象共享的信息。
常量数据成员和静态常量数据成员有什么区别?如何初始化常量数据成员?如何初始化静态常量数据成员?
常量的数据成员指得是那些在对象生成时给定了初值,在整个对象的生命周期中,该数据成员的值是不能变的。常量数据成员的值必须在构造函数的初始化列表中进行初始化。静态的常量数据成员是整个类所有对象共享的一个常量。对整个类而言,不管定义了多少个对象,该成员永远只有一份拷贝。静态常量数据成员的值是在定义类时给定。
静态成员函数不能操作非静态的数据成员,那么非静态的成员函数能否操作静态的数据成员?为什么?
因为静态成员函数没有隐含的this指针,所以不能够操作非静态的数据成员。静态的数据成员是所有对象共享的数据成员,在逻辑上是属于每一个对象的,所以非静态的成员函数可以操作静态的数据成员。
静态成员变量的初始化不能放在类的构造函数中;
为静态成员分配空间称为静态成员的定义
静态成员的定义一般出现在类的实现文件中。如在SavingAccount类的实现文件中,必须要如下的定义:
double SavingAccount::rate = 0.05;
该定义为rate分配了空间,并给它赋了一个初值0.05。
如果没有这个定义,连接器会报告一个错误。
(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值。
(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其他函数访问。
(3)在模块内的static函数只可以被这一模块内的其他函数调用。这个函数的使用范围被限制在声明它的模块内。
(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
静态成员的好处就是内存中只有一份拷贝,可以直接通过类名访问。